Salvo is an extremely simple and powerful Rust web backend framework. Only basic Rust knowledge is required to develop backend services.
🎯 Features
- Built with Hyper 1 and Tokio;
- HTTP1, HTTP2 and HTTP3;
- Unified middleware and handle interface;
- Router can be nested infinitely, and multiple middlewares can be attached to any router;
- Integrated Multipart form processing;
- Support WebSocket, WebTransport;
- Support OpenAPI, generate OpenAPI data automatic;
- Support Acme, automatically get TLS certificate from let's encrypt;
- Support Tower service and layer;
⚡️ Quick Start
You can view samples here, or view official website.
🛠️ Salvo CLI
Salvo CLI is a command-line tool that simplifies the creation of new Salvo projects, supporting templates for web APIs, websites, databases (including SQLite, PostgreSQL, and MySQL via SQLx, SeaORM, Diesel, Rbatis), and basic middleware. You can use salvo-cli to create a new Salvo project:
install
create a new salvo project
Hello World with ACME and HTTP3
Easily implement a server that supports ACME to automatically obtain certificates and supports HTTP3.
use *;
async
async
Middleware
There is no difference between Handler and Middleware, Middleware is just Handler. So you can write middlewares without to know concepts like associated type, generic type. You can write middleware if you can write function!!!
use ;
use *;
async
Then add it to router:
.hoop.get
new
This is a very simple middleware, it adds Header
to Response
, view full source code.
Chainable tree routing system
Normally we write routing like this:
.get.post;
with_path
.get
.patch
.delete;
with_path
Often viewing articles and article lists does not require user login, but creating, editing, deleting articles, etc. require user login authentication permissions. The tree-like routing system in Salvo can meet this demand. We can write routers without user login together:
.get
.push;
with_path
Then write the routers that require the user to login together, and use the corresponding middleware to verify whether the user is logged in:
.hoop
.push;
with_path
Although these two routes have the same path("articles")
, they can still be added to the same parent route at the same time, so the final route looks like this:
.push
.push;
new
<id>
matches a fragment in the path, under normal circumstances, the article id
is just a number, which we can use regular expressions to restrict id
matching rules, r"<id:/\d+/>"
.
You can also use <**>
, <*+>
or <*?>
to match all remaining path fragments. In order to make the code more readable, you can also add appropriate name to make the path semantics more clear, for example: <**file_path>
.
Some regular expressions for matching paths need to be used frequently, and it can be registered in advance, such as GUID:
;
register_wisp_regex
This makes it more concise when path matching is required:
.get
with_path
View full source code
File upload
We can get file async by the function file
in Request
:
async
Extract data from request
You can easily get data from multiple different data sources and assemble it into the type you want. You can define a custom type first, for example:
/// Get the data field value from the body by default.
Then in Handler
you can get the data like this:
async
You can even pass the type directly to the function as a parameter, like this:
async
View full source code
OpenAPI Supported
Perfect support for OpenAPI can be achieved without making significant changes to the project.
async
async
async
async
More Examples
Your can find more examples in examples folder. You can run these examples with the following command:
You can use any example name you want to run instead of basic-auth
here.
🚀 Performance
Benchmark testing result can be found from here:
https://web-frameworks-benchmark.netlify.app/result?l=rust
https://www.techempower.com/benchmarks/#section=data-r22
🩸 Contributing
Contributions are absolutely, positively welcome and encouraged! Contributions come in many forms. You could:
- Submit a feature request or bug report as an issue;
- Comment on issues that require feedback;
- Contribute code via pull requests;
- Publish Salvo-related technical articles on blogs or technical platforms。
All pull requests are code reviewed and tested by the CI. Note that unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Salvo by you shall be dual licensed under the MIT License, without any additional terms or conditions.
☕ Supporters
Salvo is an open source project. If you want to support Salvo, you can ☕ buy me a coffee here.
⚠️ License
Salvo is licensed under either of
-
Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0).
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT).